/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package koor.persistent;

import java.util.HashMap;
import java.util.List;
import koor.entity.AbstractEntity;
import koor.hibernate.HibernateUtil;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

public abstract class AbstractDAO<T extends AbstractEntity> implements BaseDAO<T> {

    protected Class<T> clazz;
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

    @Override
    public void setClazz(final Class<T> clazzToSet) {
        clazz = clazzToSet;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T findOne(final Long id) {
        Session session = null;
        T entity = null;
        try {
            session = getSession();
            entity = (T) session.get(clazz, id);
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return entity;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll() {
        Session session = null;
        List<T> entityList = null;
        try {
            session = getSession();
            entityList = session.createQuery("from " + clazz.getName()).list();
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return entityList;
    }

    @Override
    public long save(T entity) {
        Session session = null;
        long id = -1;
        try {
            session = getSession();
            id = (Long) session.save(entity);
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return id;
    }

    @Override
    public void update(T entity) {
        Session session = null;
        try {
            session = getSession();
            session.merge(entity);
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    @Override
    public void delete(T entity) {
        Session session = null;
        try {
            session = getSession();
            session.delete(entity);
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    @Override
    public void deleteById(Long entityId) {
        T entity = findOne(entityId);
        delete(entity);
    }

    @Override
    public List<T> findByCriteria(String param, String name) {
        Session session = null;
        List<T> entityList = null;
        try {
            session = getSession();
            entityList = (List<T>) session.createCriteria(clazz).createCriteria(name).add(Restrictions.eq(name, param)).list();
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return entityList;
    }

    @Override
    public List<T> findByCriteria(HashMap<String, String> params) {
        Session session = null;
        List<T> entityList = null;
        try {
            session = getSession();
            Criteria criteria = session.createCriteria(clazz);
            for (String name : params.keySet()) {
                criteria.createCriteria(name).add(Restrictions.eq(name, params.get(name)));
            }
            entityList = criteria.list();
        } catch (Exception e) {
            //
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return entityList;

    }

    protected final Session getSession() {
        return sessionFactory.openSession();
    }
}
